AWS ParallelClusterはどうやってコンピュートフリートをスケールさせるのか調べてみた
AWS ParallelClusterを利用すると、AWS上で簡単にHPC環境を構築できます。
従来のジョブスケジューラ (SGE、Slurm、Torque) を使用してクラスターを構築すると、AWS ParallelCluster は ジョブスケジューラーとAmazon Auto Scaling Group(以下ASG)の両方と連携しながらコンピュートフリートをスケーリングさせます。
スケールアウト・インそれぞれの処理の流れをドキュメント・ソースコードから確認する機会がありましたので、共有します。
スケーリングに関連するコンポーネント・設定
ジョブスケジューラー
ジョブスケジューラーはジョブやジョブを実行するノード情報を管理します。
AWS ParallelCluster はジョブスケジューラーとして AWS Batch と従来型(SGE/Slurm/Torque)に対応しています。 ASG と連動するのは、後者の従来型です。
Amazon Auto Scaling Group(ASG)
Amazon Auto Scaling GroupはEC2インスタンス数のスケーリングを管理します。 コンピュートフリートはこの ASG を利用して管理され、ジョブスケジューラーと連携しながらフリートサイズを増減させます。
フリートサイズに関係するには、以下のパラメーターです。
- 希望する容量(
desired capacity
) - 最大キャパシティ(
maximum
) - 最小キャパシティ(
minimum
)
Amazon SQS
Amazon SQSはメッセージキューサービスです。 コンピュートノードの追加・削除とジョブスケジューラーの連携は、このSQSを介しておこなれます。
jobwatcher プロセス
ジョブスケジューラーと通信し、スケールアウトが必要か判断するプロセスです。
ヘッドノードで実行されます。
sqswatcher プロセス
ノードの追加・削除時には、SQSにメッセージ送信されます。
これらメッセージを受け取り、ジョブスケジューラーなど連携するプロセスです。
ヘッドノードで実行されます。
nodewatcher プロセス
コンピュートノードがジョブを処理しないまま一定期間(AWS ParallelClustter設定ファイルのscaledown_idletime
)をすぎた場合、ノードを終了させるプロセスです。
コンピュートノードで実行されます。
compute_ready プログラム
コンピュートノードのブートストラップ処理完了を SQS にメッセージ送信するプログラムです。
プログラムのパスは /opt/parallelcluster/scripts/compute_ready
です。
AWS ParallelCluster の設定ファイル
コンピュートフリートのスケーリングに関係するパラメーターは以下です。
initial_queue_size
: コンピュートフリートの初期起動数max_queue_size
: コンピュートフリートの最大起動数maintain_initial_size
: フリートの最低起動数を制御。true の場合は最小は initial_queue_sizeに、false の場合は 0scaledown_idletime
: コンピュートノードのターミネート判定時に利用するアイドル時間
検証環境
- AWS ParallelCluster 2.8.1
- ジョブスケジューラー : Slurm
- OS : Amazon Linux 2
スケールアウト処理の流れ
稼働中のクラスターにおいて、ノード数がASGの上限に達しておらず、ジョブのキューイングからノード追加が必要な場合の処理です。
新規クラスター作成時には、実質的に(2)以降の処理が動作しているはずです。
ノード追加命令の流れ
この節の処理は、ヘッドノードで動作する jobwatcher
プロセスが行います。
(1)ジョブキューのポーリング
ジョブスケジューラーのジョブキューをポーリングし、ノード追加が必要かチェックします。
(2)ASGのサイズ変更
コンピュートノードが足りない場合、ASG::UpdateAutoScalingGroup API でASG のインスタンス数を増やします。
ノード追加の流れ
(3)新規EC2インスタンス追加
ASG が新規にEC2インスタンスを追加します。
(4)ブートストラップ処理
EC2インスタンスのブートストラップ処理が完了すると、/opt/parallelcluster/scripts/compute_ready
が SQS に準備完了メッセージを送ります。
SQSメッセージ送信処理の流れ
この節の処理は、ヘッドノードで動作する sqswatcher
プロセスが行います。
(5)SQSキューのポーリング
SQS の新規キューをポーリングします。
※ノードの追加・削除で同じSQSキュー・プログラムを利用します。
(6)新ノードをジョブスケジューラーに通知
ノード追加のメッセージだった場合、ジョブスケジューラーに追加します。
(7)DynamoDB に追加
ノード情報をDynamoDBに追加します。
スケールイン
稼働中のクラスターにおいて、ノード数がASGの下限に達しておらず、余剰ノードの削除が必要な場合の処理です。
ノード削除命令の流れ
この節の処理は、各コンピュートノードで動作する nodewatcher
プロセスが行います。
(1)ジョブキューの確認
ジョブスケジューラーのジョブキューをポーリングします。
ノードがジョブを処理してておらず、保留中のジョブもなく、ノードが一定期間アイドル状態であり、ノード数がASGの下限に達していない場合、削除処理に入ります。
(2)ASGのサイズ変更
ASG::TerminateInstanceInAutoScalingGroup API で自ノードをターミネートするように命令します。
SQSメッセージの送信処理の流れ
(3)ASGのターミネートイベントをSNSに通知
ASG のスケーリングイベントはAmazon SNSに通知することができます。
この機能を利用し、EC2インスタンスのターミネートイベント(autoscaling: EC2_INSTANCE_TERMINATE
)をAmazon SNSに通知します。
(4)SNSメッセージをSQSに通知
Amazon SNSのサブスクライブ機能を使い、SNS に送信したメッセージを SQS に配信します。
SQSメッセージの受信処理の流れ
この節の処理は、ヘッドノードで動作する sqswatcher
プロセスが行います。
(5)SQSキューのポーリング
SQS の新規キューをポーリングします。
※ノードの追加・削除で同じSQSキュー・プログラムを利用します。
(6)破棄ノードをジョブスケジューラから削除通知
ノード削除のメッセージだった場合、ジョブスケジューラーから削除します。
(7)DynamoDB から削除
ノード情報をDynamoDBから削除します。
最後に
AWS ParallelClusterで従来のジョブスケジューラ (SGE、Slurm、Torque) を使用してクラスターを構築すると、ASGでクラスターが管理されます。 このASGのスケーリングの流れを確認しました。
- ジョブスケジューラーがリソース不足と判断したときは ASG::UpdateAutoScalingGroup API でノードを増やし
- ノードのアイドル状態が続くときは ASG::TerminateInstanceInAutoScalingGroup API でノードを破棄します。
ジョブキューに対して期待通りにスケーリングしない場合、処理の流れとヘッド・コンピュートノードの /var/log 以下のログを確認しましょう。